# -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python
import shutil

from cerbero.tools.libtool import LibtoolLibrary
from cerbero.tools.pkgconfig import PkgConfigWritter

class Recipe(recipe.Recipe):
    name = 'gnustl'
    version = '0.1'
    licenses = [License.LGPLv2_1Plus]
    stype = SourceType.CUSTOM
    btype = BuildType.CUSTOM
    runtime_dep = True

    files_stl = [
            'lib/libc++_shared.so']
    files_devel= [
            'lib/pkgconfig/gnustl.pc',
            'lib/libgnustl.la',
            'lib/libandroid_support.a'
            ]

    def prepare(self):
        if self.config.target_platform != Platform.ANDROID:
            raise InvalidRecipeError(self, "Invalid platform")
        v = DistroVersion.get_android_api_version(self.config.target_distro_version)

    async def compile(self):
        libdir = os.path.join(self.config.prefix, 'lib')
        if not os.path.exists(libdir):
            os.makedirs(libdir)

        # Generate libraries that aren't copied from the NDK
        v = DistroVersion.get_android_api_version(self.config.target_distro_version)
        if v >= 21:
            shell.call(" ".join([self.get_env('AR'), 'rc', os.path.join(libdir, 'libandroid_support.a')]), env=self.env)
        if self.config.target_arch != Architecture.ARMv7:
            shell.call(" ".join([self.get_env('AR'), 'rc', os.path.join(libdir, 'libunwind.a')]), env=self.env)

    async def install(self):
        stl_prefix = os.path.join(self.config.toolchain_prefix, 'sources',
                  'cxx-stl', 'llvm-libc++')
        if self.config.target_arch == Architecture.X86:
            libarch = 'x86'
        elif self.config.target_arch == Architecture.X86_64:
            libarch = 'x86_64'
        elif self.config.target_arch == Architecture.ARMv7:
            libarch = 'armeabi-v7a'
        elif self.config.target_arch == Architecture.ARM64:
            libarch = 'arm64-v8a'
        elif self.config.target_arch == Architecture.ARM:
            libarch = 'armeabi'
        else:
            raise FatalError("Unsupported Android architecture %s" % self.config.target_arch)
        stl_libdir = os.path.join(stl_prefix, 'libs', libarch)
        libdir = os.path.join(self.config.prefix, 'lib')
        if not os.path.exists(libdir):
            os.makedirs(libdir)

        # Copies libraries to the prefix
        shutil.copy(os.path.join(stl_libdir, 'libc++_shared.so'),
                    os.path.join(libdir, 'libc++_shared.so'))
        v = DistroVersion.get_android_api_version(self.config.target_distro_version)
        if v < 21:
            shutil.copy(os.path.join(stl_libdir, 'libandroid_support.a'),
                        os.path.join(libdir, 'libandroid_support.a'))

        if self.config.target_arch == Architecture.ARMv7:
            shutil.copy(os.path.join(stl_libdir, 'libunwind.a'),
                        os.path.join(libdir, 'libunwind.a'))

        # Create a libtool library for gnustl (libgnustl.la)
        lib = LibtoolLibrary('gnustl', None, None, None, libdir,
                self.config.target_platform)
        lib.change_value('dlname', 'libc++_shared.so')
        lib.change_value('library_names', 'libc++_shared.so libc++_shared.so libc++_shared.so')
        lib.change_value('old_library', '')
        lib.change_value('dependency_libs', '-lc++_shared' +
                                (' %s/libandroid_support.a' % (libdir) if v < 21 else '') +
                                (' %s/libunwind.a' % (libdir) if self.config.target_arch == Architecture.ARMv7 else ''))
        lib.save()

        # Create pkg-config file (gnustl.pc)
        pkgdir = os.path.join(self.config.prefix, 'lib', 'pkgconfig')
        if not os.path.exists(pkgdir):
            os.makedirs(pkgdir)
        stl_pc = PkgConfigWritter('gnustl', 'gnustl', '2.0',
                '', '-L${libdir} ${libdir}/libc++_shared.so' +
                (' ${libdir}/libandroid_support.a ' if v < 21 else '') +
                (' ${libdir}/libunwind.a ' if self.config.target_arch == Architecture.ARMv7 else '') +
                '',
                # FIXME: slurp these headers into the cerbero directory somehow so that they are usable from c++ applications
                '-I%s/include' % (stl_prefix) +
                (' -I%s/sources/android/support/include ' % self.config.toolchain_prefix if v < 21 else ''),
                self.config.prefix)
        stl_pc.rel_incldir = 'include'
        stl_pc.save('gnustl', pkgdir)
